package com.example.spider.proxy;

import com.example.spider.proxy.core.ProxyInfo;
import com.example.spider.proxy.core.ProxyStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;

/**
 * 任务上下文代理提供
 */
@Component
public class TaskContextProxyProvider implements ProxyProvider {

    @Autowired
    private ProxyPool proxyPool;


    @Value("${spider.proxy.strategy:no}")
    private ProxyStrategy strategy;

    /**
     * 全局负载均衡下标
     **/
    private final AtomicInteger roundRobinIndex = new AtomicInteger(0);

    private final AtomicInteger weightRoundRobinIndex = new AtomicInteger(0);

    @Override
    public ProxyInfo getProxy() {
        // 获取上下文的代理策略
        ProxyInfo exceptedProxy = SpiderContextHolder.getTask().getExceptedProxy();
        if (exceptedProxy != null) {
            SpiderContextHolder.setProxyInfo(exceptedProxy);
            return exceptedProxy;
        }
        String aimUrl = "xxx";

        // 未拿到代理
        ProxyInfo proxyInfo = getProxyWithStrategy(strategy, aimUrl);
        proxyInfo = proxyInfo == null ? failBackProxy() : proxyInfo;

        SpiderContextHolder.setProxyInfo(proxyInfo);

        return proxyInfo;
    }

    private ProxyInfo getProxyWithStrategy(ProxyStrategy strategy, String aimUrl) {
        if (strategy == null) {
            return null;
        }
        // 执行策略
        Function<ProxyInfo, Boolean> filter = aimUrl.contains("https:") ? ProxyInfo::getSupportHttps : px -> true;
        ProxyInfo p = switch (strategy) {
            case no -> ProxyPool.NO_PROXY;
//            case given:
//                // 使用任务里的
//                //return new Proxy(Proxy.Type.HTTP, new InetSocketAddress("39.99.54.91", 80)) // 高匿名 中国 北京  联通
//                return new Proxy(Proxy.Type.HTTP, new InetSocketAddress("47.102.110.19", 7890));
//            case highestSuccessPercentageFirst:
//            case minCostFirst:
//            case highestScoreFirst:

            case roundRobin -> proxyPool.getNearByIndex(roundRobinIndex, false, filter);
            case weightRoundRobin -> proxyPool.getNearByIndex(weightRoundRobinIndex, true, filter);
            case urlHash -> proxyPool.getUseHash(aimUrl, true, filter);
            case random -> proxyPool.getRandomProxy(false, filter);
            //case weightRandom-> proxyPool.getRandomProxy(true);
            default -> proxyPool.getRandomProxy(true, filter);
        };
        return p;
    }

    /**
     * 默认策略
     *
     * @return 无代理
     */
    protected ProxyInfo failBackProxy() {
        // 从上下文判断是否支持无代理请求
        //boolean includeLocal = true;
        return ProxyPool.NO_PROXY;
    }

}
